package io.bhex.app.optimize;

import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.Log;
import android.view.Choreographer;

/**
 * created by gongdongyang
 * on 2020/2/26
 */
public class FrameAnalyze {

    public static boolean start() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            SMFrameCallback.getInstance().mIsOpen = true;
            SMFrameCallback.getInstance().lastFrameTimeNanos = 0;
            SMFrameCallback.getInstance().postCallback();
            return true;
        }
        return false;
    }

    public static void stop() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            SMFrameCallback.getInstance().stopInternal();
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    private static class SMFrameCallback implements Choreographer.FrameCallback {

        private static final String TAG = "SMFrameCallback";

        private static final float deviceRefreshRateMs = 16.6f;

        private static SMFrameCallback sInstance;

        private long lastFrameTimeNanos = 0;//纳秒为单位
        private boolean mIsOpen;

        private static SMFrameCallback getInstance() {
            if (sInstance == null) {
                sInstance = new SMFrameCallback();
            }
            return sInstance;
        }

        private void postCallback() {
            if (mIsOpen) {
                Choreographer.getInstance().postFrameCallback(this);
            }
        }

        private void stopInternal() {
            mIsOpen = false;
        }

        @Override
        public void doFrame(long frameTimeNanos) {
            if (lastFrameTimeNanos == 0) {
                lastFrameTimeNanos = frameTimeNanos;
                postCallback();
                return;
            }
            float value = (frameTimeNanos - lastFrameTimeNanos) / 1000000.0f;

            final int skipFrameCount = skipFrameCount(lastFrameTimeNanos, frameTimeNanos, deviceRefreshRateMs);
            Log.e(TAG, "两次绘制时间间隔value=" + value + "  skipFrameCount=" + skipFrameCount + "  frameTimeNanos=" + frameTimeNanos + "  currentFrameTimeNanos=" + frameTimeNanos + "");
            lastFrameTimeNanos = frameTimeNanos;
            postCallback();
        }


        /**
         * 计算跳过多少帧
         *
         * @param start
         * @param end
         * @param devicefreshRate
         * @return
         */
        private int skipFrameCount(long start, long end, float devicefreshRate) {
            int count = 0;
            long diffNs = end - start;
            long diffMs = Math.round(diffNs / 1000000.0f);
            long dev = Math.round(devicefreshRate);
            if (diffMs > dev) {
                long skipCount = diffMs / dev;
                count = (int) skipCount;
            }
            return count;
        }
    }
}
